package de.g18.it0a.jlaser.jlf;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import de.g18.it0a.jlaser.domain.Position;
import de.g18.it0a.jlaser.domain.RoomConfiguration;
import de.g18.it0a.jlaser.exception.InitializationException;
import de.g18.it0a.jlaser.exception.JLFParseException;


public class JLFConverter {

    private JLFConverter() {
        // prevent instantiation
    }

    public static RoomConfiguration valueOf(File aFile) throws InitializationException, FileNotFoundException, JLFParseException {
        LineNumberReader lnr = new LineNumberReader(new InputStreamReader(new FileInputStream(aFile)));
        String line = null;
        String fileContent = "";
        try {
            while ((line = lnr.readLine()) != null) {
                fileContent += line + "\n";
            }
        } catch (IOException e) {
            throw new IllegalStateException("An error occured while reading '" + aFile.getAbsolutePath() + "'", e);
        }
        return valueOf(fileContent);
    }

    public static RoomConfiguration valueOf(String aFileContent) throws InitializationException, JLFParseException {
        JLFRoomDefinition roomDefinition = null;
        List<JLFVetrineDefinition> vetrineDefinitions = new ArrayList<JLFVetrineDefinition>();

        int lineNumber = 1;
        StringTokenizer tokenizer = new StringTokenizer(aFileContent, "\n");
        while (tokenizer.hasMoreTokens()) {
            String line = tokenizer.nextToken();
            if (isComment(line)) {
                continue;
            }

            try {
                if (JLFRoomDefinition.isValidDefinition(line)) {
                    roomDefinition = JLFRoomDefinition.valueOf(line);
                } else if (JLFVetrineDefinition.isValidDefinition(line)) {
                    vetrineDefinitions.add(JLFVetrineDefinition.valueOf(line));
                } else {
                    throw new JLFParseException(lineNumber, 0, line);
                }
            } catch (ParseException e) {
                throw new JLFParseException(lineNumber, e.getErrorOffset(), line, e);
            }
            lineNumber++;
        }

        if (roomDefinition == null) {
            return null;
        }

        List<Position> vetrinePositions = new ArrayList<Position>();
        for (JLFVetrineDefinition def : vetrineDefinitions) {
            vetrinePositions.add(def.getPosition());
        }
        return new RoomConfiguration(roomDefinition.getWidth(), roomDefinition.getHeight(), new Position(0, 0), vetrinePositions);
    }

    public static String valueOf(RoomConfiguration aConfig) {
        String result = ";Raum\n"
                      + JLFRoomDefinition.valueOf(aConfig).toString() + "\n"
                      + "\n"
                      + ";Vitrinen\n";
        for (Position pos : aConfig.getVetrinePositions()) {
            result += JLFVetrineDefinition.valueOf(pos).toString() + "\n";
        }
        return result;
    }

    private static boolean isComment(String aLine) {
        return aLine.startsWith(";");
    }
}
